package secrpc

import (
	"context"
	"dub/define/grpcmodel"
	"dub/utils"
	"fmt"
)

type SecRpcUse struct {
	log   *utils.Logger
	dbRpc *utils.RpcProxy
}

//用户名登录
func (s *SecRpcUse) Login(ctx context.Context, arg *grpcmodel.ModelSecRpcUseReqFind) (reply *grpcmodel.ModelSecRpcUseResLogin, err error) {
	reply = &grpcmodel.ModelSecRpcUseResLogin{}
	if arg.GetLoginName() == "" || arg.GetLoginPwd() == "" {
		reply.Err = 3
		return
	}
	//用户信息
	use_args := &grpcmodel.ModelDbRpcUserReqFind{
		LoginName: arg.GetLoginName(),
	}
	db_use := grpcmodel.NewIDbRpcUserClient(s.dbRpc.Conn())
	s.log.Infof("def_func_sec_use.go Login method db_use.FindUser use_args info is %+v\n", use_args)
	use_reply, err := db_use.FindUser(s.dbRpc.Context(), use_args)
	s.log.Infof("def_func_sec_use.go Login method db_use.FindUser use_reply info is %+v\n", use_reply)
	if err != nil {
		s.log.Errorf("def_fun_sec_use.go Login method db_use.FindUser err. %v\n", err)
		reply.Err = 2
		return
	}
	reply.Err = use_reply.GetErr()
	if reply.Err > 0 {
		return
	}
	//用户名密码是否正确
	use_model := use_reply.GetModelDbRpcUser()
	if use_model.GetLoginName() != arg.GetLoginName() || use_model.GetLoginPwd() != arg.GetLoginPwd() {
		reply.Err = 4
		return
	}
	reply_model := &grpcmodel.ModelSecRpcUse{}
	reply_model.UserId = use_model.GetUserId()
	reply_model.UserName = use_model.GetUserName()
	reply_model.LoginName = use_model.GetLoginName()
	reply_model.LoginPwd = use_model.GetLoginPwd()
	reply_model.UserStatus = use_model.GetUserStatus()
	reply_model.UserAddTime = use_model.GetUserAddTime()
	reply_model.UserAddId = use_model.GetUserAddId()

	reply.ModelSecRpcUse = reply_model

	//角色信息
	role_args := &grpcmodel.ModelDbRpcRoleReqFind{
		UserId: reply_model.UserId,
	}
	db_role := grpcmodel.NewIDbRpcRoleClient(s.dbRpc.Conn())
	s.log.Infof("def_func_sec_use.go Login method db_role.FindRole role_args info is %+v\n", role_args)
	role_reply, err := db_role.FindRole(s.dbRpc.Context(), role_args)
	s.log.Infof("def_func_sec_use.go Login method db_role.FindRole role_reply info is %+v\n", role_reply)
	if err != nil {
		s.log.Errorf("def_fun_sec_use.go Login method s.dbRpc.Call RoleRpc.FindRoleByUseId err. %v\n", err)
		reply.Err = 2
		return
	}
	reply.Err = role_reply.GetErr()
	if reply.Err > 0 {
		return
	}
	role_model := role_reply.GetModelDbRpcRole()
	if role_model != nil {
		reply_model.RoleId = role_model.GetRoleId()
		reply_model.RoleName = role_model.GetRoleName()
		reply_model.UrAddTime = role_model.GetUrAddTime()
		reply_model.UrEditTime = role_model.GetUrEditTime()
		reply_model.UrMain = role_model.GetUrMain()
	} else {
		reply.Err = 1
		return
	}

	reply.ModelSecRpcUse = reply_model

	//权限信息
	auth_args := &grpcmodel.ModelDbRpcAuthReqFind{
		RoleId: reply_model.GetRoleId(),
	}
	db_auth := grpcmodel.NewIDbRpcAuthClient(s.dbRpc.Conn())
	s.log.Infof("def_func_sec_use.go Login method db_auth.Find auth_args info is %+v\n", auth_args)
	auth_reply, err := db_auth.Find(s.dbRpc.Context(), auth_args)
	s.log.Infof("def_func_sec_use.go Login method db_auth.Find auth_reply info is %+v\n", auth_reply)
	if err != nil {
		s.log.Errorf("def_fun_sec_use.go Login method db_auth.Find err. %v\n", err)
		reply.Err = 2
		return
	}
	reply.Err = auth_reply.GetErr()
	if reply.GetErr() > 0 || auth_reply.GetRows() == nil || len(auth_reply.GetRows()) < 1 {
		return
	}
	if reply.GetErr() == 1 {
		return
	}

	auth_all_args := &grpcmodel.ModelDbRpcAuthReqFind{}
	s.log.Infof("def_func_sec_use.go Login method db_auth.FindAll auth_all_args info is %+v\n", auth_all_args)
	auth_all_reply, err := db_auth.FindAll(s.dbRpc.Context(), auth_all_args)
	s.log.Infof("def_func_sec_use.go Login method db_auth.FindAll auth_all_reply info is %+v\n", auth_all_reply)
	if err != nil {
		s.log.Errorf("def_fun_sec_use.go Login method s.dbRpc.Call AuthRpc.FindAllAuths err. %v\n", err)
		reply.Err = 2
		return
	}
	reply.Err = auth_all_reply.GetErr()
	if reply.GetErr() > 0 || auth_all_reply.GetAuths() == nil || len(auth_all_reply.GetAuths()) < 1 {
		return
	}
	if reply.GetErr() == 1 {
		return
	}

	use_entity_auth_map := make(map[uint32]string)
	reply.Auths = make([]*grpcmodel.ModelSecRpcAuth, 0)
	for _, auth := range auth_reply.GetRows() {
		if arg.ReqType == auth.GetAuthType() {
			sec_auth := &grpcmodel.ModelSecRpcAuth{
				AuthId:              auth.GetAuthId(),
				AuthPreId:           auth.GetAuthPreId(),
				AuthName:            auth.GetAuthName(),
				AuthMicroServerName: auth.GetAuthMicroServerName(),
				AuthUrl:             auth.GetAuthUrl(),
				AuthShowStatus:      auth.GetAuthShowStatus(),
				AuthType:            auth.GetAuthType(),
			}

			for _, enauth := range auth_all_reply.GetAuths() {
				len_enauth := len(enauth.GetAuthUrl())
				if auth.GetAuthId() == enauth.GetAuthId() && len_enauth > 0 {
					use_entity_auth_map[enauth.GetAuthId()] = fmt.Sprintf("[%s]%s", enauth.GetAuthMicroServerName(), enauth.GetAuthUrl())
				}

				if auth.GetAuthNeedUrls() != nil && len(auth.GetAuthNeedUrls()) > 0 {
					binary_auth := fmt.Sprintf("%b", auth.GetRoleAuthConf())
					len_binary_auth := len(binary_auth)
					for i, needId := range auth.GetAuthNeedUrls() {
						//binary_auth是数字转换的二进制字符口串，1对应的ascii是49，0是48
						if needId == enauth.GetAuthId() && len_enauth > 0 && i < len_binary_auth && binary_auth[i] == 49 {
							use_entity_auth_map[enauth.GetAuthId()] = fmt.Sprintf("[%s]%s", enauth.GetAuthMicroServerName(), enauth.GetAuthUrl())
						}
					}
				}
			}

			reply.Auths = append(reply.Auths, sec_auth)
		}
	}

	//把用户的实体权限添加进去
	if len(use_entity_auth_map) > 0 {
		reply.PhyAuths = make([]string, 0, len(use_entity_auth_map))
		for _, val := range use_entity_auth_map {
			reply.PhyAuths = append(reply.PhyAuths, val)
		}
	}

	return
}

var _secRpcUse *SecRpcUse

func NewSecRpcUse(log *utils.Logger, dbRpc *utils.RpcProxy) *SecRpcUse {
	if _secRpcUse == nil {
		_secRpcUse = &SecRpcUse{
			log:   log,
			dbRpc: dbRpc,
		}
	}
	return _secRpcUse
}
